前言
Logos 是 Theos 的一个组件,它允许程序员使用一组特殊的预处理器指令来编写钩子,简洁高效。
做过 iOS 逆向开发的朋友应该非常熟悉,这里笔者将介绍如何在 Mac app 上使用 Logos。
可能用到的工具
- Theos
- optool/insert_dylib
- unsign (optional)
一个简单的例子
编写一个简单的 demo,大概就是软件正中一个按钮,点击之后 alert(“hi!”)。核心代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)sayHi:(NSButton *)sender {
NSAlert *alert = NSAlert.new;
alert.messageText = @"hi!";
alert.alertStyle = NSAlertStyleInformational;
[alert runModal];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
@end
我们的目标是注入 sayHi 这个方法,使点击按钮之后不再说“hi!”,而是“hello world!”
编写 Logos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22%config(generator=internal)
// You don't need to #include <substrate.h>, it will be done automatically, as will
// the generation of a class list and an automatic constructor.
%hook ViewController
// Hooking an instance method with an argument.
- (void)sayHi:(id)argument {
NSAlert *r15 = [[NSAlert alloc] init];
[r15 setMessageText:@"hello world!"];
[r15 setAlertStyle:0x1];
[r15 runModal];
}
// Always make sure you clean up after yourself; Not doing so could have grave consequences!
%end
%ctor {
NSLog(@"!!!!!!inject success!!!!!!!");
}
将以上代码保存为一个 Tweak.xm 文件(名字后缀名随意),放在与 SayHi.app 同级目录下,便于后续操作。
然后我们使用 Theos 的语法分析来把 Logos 转换成普通代码
$THEOS/bin/logos.pl Tweak.xm > abc.mm
注意 abc 应该有 mm 作为后缀名,用于告诉 clang 目标语言类型使用 clang 编译转换后的普通代码,并将结果放到 app 包内
clang -shared -undefined dynamic_lookup -o ./SayHi.app/Contents/MacOS/lib.dylib ./abc.mm
使用 optool/insert_dylib 往 SayHi 的 MachO 头部添加我们刚刚编译的 lib.dylib
optool install -c load -p @executable_path/lib.dylib -t ./SayHi.app/Contents/MacOS/SayHi
如果你的 Mac app 没有签名的话,此时应该已经达成我们的需求了。但是实践中我们肯定不是对自己导出的未签名 Mac app 下黑手。所以需要去掉这个签名或重签名。因为笔者没有钱买开发者账号,故不知道如何重签名。
- 使用 codesign 去除签名
codesign --remove-signature SayHi.app
此时我们的需求已经达成
但是 codesign 有一个 bug,在删除代码签名之后没有修复 MachO Header 的偏移,会导致生成的 MachO 文件畸形。笔者曾经就遇见一个不到 1m 的小程序在移除签名后膨胀到 2g 大小。
所以笔者建议使用开源社区的代替方案——unsign
后记
笔者把上面的繁琐命令行操作整合为一个脚本,在这里也顺便分享出来
1 |
|